package com.itlong.cloud.app.service.impl;

import com.alibaba.fastjson.JSON;
import com.itlong.cloud.POJO.PO.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.app.dao.IAppUserLykzAccountDao;
import com.itlong.cloud.app.service.IAppLykzCloudIntercomAccountService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.random.LogicIdUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <desc>
 *     APP的我的板块服务层实现类
 * </desc>
 *
 * @createDate 2017/10/10
 */
@Service
@RefreshScope
public class AppLykzCloudIntercomAccountServiceImpl implements IAppLykzCloudIntercomAccountService{

    @Value("${" + PlatformConstants.APP_USER_TOKEN_KEY + "}")
    String userTokenKey;

    @Value("${" + PlatformConstants.LYKZ_ACCOUNT_SID + "}")
    String LYKZ_ACCOUNT_SID;
    @Value("${" + PlatformConstants.LYKZ_ACCOUNT_TOKEN + "}")
    String LYKZ_ACCOUNT_TOKEN;
    @Value("${" + PlatformConstants.LYKZ_APPID + "}")
    String LYKZ_APPID;
    @Value("${" + PlatformConstants.LYKZ_SOFT_VERSION + "}")
    String LYKZ_SOFT_VERSION;
    @Value("${" + PlatformConstants.LYKZ_URL + "}")
    String LYKZ_URL;
    @Value("${" + PlatformConstants.LYKZ_PORT + "}")
    String LYKZ_PORT;

    ExecutorService cachedThreadPool;

    @PostConstruct
    public void init(){
        cachedThreadPool = Executors.newFixedThreadPool(1);
    }


    @Autowired
    private IAppUserLykzAccountDao iAppUserLykzAccountDao;

    private static final Logger LOG = LoggerFactory.getLogger(AppLykzCloudIntercomAccountServiceImpl.class);

    /**
     * <desc>
     *      创建灵云快智云对讲用户账号
     * </desc>
     *
     * @param userId 用户id
     * @param phoneNum 手机号
     * @param lykzAppId 灵云快智为接入云对讲SDK分配的应用ID
     * @return
     * @author Juguang.S
     * @createDate 2018/08/23
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public CloudIntercomAccountInfoPO createLykzCloudIntercomAccount(String userId, String phoneNum,String lykzAppId,String lykzUserId) throws Exception {

        if(StringUtils.isEmpty(lykzUserId)){
            int machineId = 1;
            int hashCodeV = UUID.randomUUID().toString().hashCode();
            if(hashCodeV < 0) {//有可能是负数
                hashCodeV = - hashCodeV;
            }
            lykzUserId = String.format("%s%s",phoneNum,machineId + String.format("%015d", hashCodeV));
        }

        //SigParameter MD5（账户Id + 账户授权令牌 + 时间戳），共32位(注:转成大写)
        SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowTime = sd.format(new Date());
        String sigParameter = Md5EncryptUtil.md5(String.format("%s%s%s",LYKZ_ACCOUNT_SID,LYKZ_ACCOUNT_TOKEN,nowTime)).toUpperCase();
        String url = "http://"+LYKZ_URL+":"+LYKZ_PORT+"/ucsrtc-rest-api/"+LYKZ_SOFT_VERSION+"/Accounts/"+LYKZ_ACCOUNT_SID+"/Clients?sig="+sigParameter;
        Map<String,Object> params = new HashMap<>();
        Map<String,String> map = new HashMap<>();
        if(StringUtils.isNotEmpty(lykzAppId)){
            map.put("appId",lykzAppId);
        }else{
            map.put("appId",LYKZ_APPID);
        }
        map.put("userId",lykzUserId);
        map.put("mobile",phoneNum);
        params.put("client",map);
        String paramsStr = JSON.toJSONString(params);

        String responseStr = HttpProtocolUtil.httpPostByLykz(url,paramsStr,nowTime,LYKZ_ACCOUNT_SID);
        if(StringUtils.isNotEmpty(responseStr)){
            Map<String, Object> jsonToMap = JsonUtil.JsonToMap(responseStr);
            if(jsonToMap != null && !jsonToMap.isEmpty()){
                Map<String, Object> jsonToMapResp = JsonUtil.JsonToMap(jsonToMap.get("resp").toString());
                if(jsonToMapResp != null && !jsonToMapResp.isEmpty()){
                    String respCode = jsonToMapResp.get("respCode").toString();
                    if(respCode.equals("000000")){
                        String client = jsonToMapResp.get("client").toString();
                        Map<String, Object> jsonToMapClient = JsonUtil.JsonToMap(client);
                        String clientNumber = jsonToMapClient.get("clientNumber").toString();
                        String clientPwd = jsonToMapClient.get("clientPwd").toString();
                        String loginToken = jsonToMapClient.get("loginToken").toString();
                        String createDate = jsonToMapClient.get("createDate").toString();
                        lykzUserId = jsonToMapClient.get("userId").toString();

                        CloudIntercomAccountInfoPO  infoPO = new CloudIntercomAccountInfoPO();
                        String lykzId = LogicIdUtil.bussinessId();
                        infoPO.setCloudIntercomAccountId(lykzId);
                        infoPO.setAccountType(1);
                        infoPO.setAccount(clientNumber);
                        infoPO.setToken(loginToken);
                        infoPO.setClientPwd(clientPwd);
                        infoPO.setClientUserId(lykzUserId);
                        infoPO.setStatus(1);
                        infoPO.setAppid(LYKZ_APPID);
                        infoPO.setCreateTime(new Date());
                        Integer result = null;
                        try {
                            result = iAppUserLykzAccountDao.save(SqlUtil.durableData(infoPO, PlatformConstants.TABLE_SAVE));
                        } catch (Exception e) {
                            throw new DataAccessException("【USER_userCreateLykzAccount】灵云快智账号信息保存异常",e);
                        }
                        if(result>0){
                            iAppUserLykzAccountDao.updateAppUserInfo(userId,lykzId);
                        }
                    return infoPO;
                    }else{
                        LOG.info(String.format("%s%s","响应状态码未成功，respCode：",respCode));
                    }

                }
            }
        }
        return null;
    }

    /**
     * <desc>
     *      根据手机号查询灵云快智云对讲用户账号
     * </desc>
     *
     * @param phoneNum 手机号
     * @param lykzAppId 灵云快智为接入云对讲SDK分配的应用ID
     * @return
     * @author Juguang.S
     * @createDate 2018/08/23
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Map<String,String> getLykzCloudIntercomAccountByMoblie(String phoneNum,String lykzAppId) throws Exception {

        //SigParameter MD5（账户Id + 账户授权令牌 + 时间戳），共32位(注:转成大写)
        SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmss");
        String nowTime = sd.format(new Date());
        String sigParameter = Md5EncryptUtil.md5(String.format("%s%s%s",LYKZ_ACCOUNT_SID,LYKZ_ACCOUNT_TOKEN,nowTime)).toUpperCase();
        String host = "http://"+LYKZ_URL+":"+LYKZ_PORT+"/ucsrtc-rest-api/"+LYKZ_SOFT_VERSION+"/Accounts/"+LYKZ_ACCOUNT_SID;
        String path = "/ClientsByMobile";
        String method = "GET";

        final Base64.Encoder encoder = Base64.getEncoder();
        final String context = String.format("%s%s%s",LYKZ_ACCOUNT_SID,":",nowTime);
        final byte[] textByte = context.getBytes("UTF-8");
        //编码
        final String authorization = encoder.encodeToString(textByte);

        Map<String, String> headers = new HashMap<>();
        headers.put("Authorization", authorization);
        headers.put("Accept", "application/json;");
        headers.put("Content-Type", "application/json;charset=utf-8");

        Map<String, String> querys = new HashMap<>();
        querys.put("sig",sigParameter);
        if(StringUtils.isNotEmpty(lykzAppId)){
            querys.put("appId",lykzAppId);
        }else{
            querys.put("appId",LYKZ_APPID);
        }
        querys.put("mobile",phoneNum);

        HttpResponse response = HttpProtocolUtil.doGet(host, path, method, headers, querys);


        if (response != null && response.getEntity() != null) {
            Map<String, Object> jsonToMap = JsonUtil.JsonToMap(EntityUtils.toString(response.getEntity()));
            if (jsonToMap != null && !jsonToMap.isEmpty()){
                Map<String, Object> jsonToMapResp = JsonUtil.JsonToMap(jsonToMap.get("resp").toString());
                if(jsonToMapResp != null && !jsonToMapResp.isEmpty()){
                    String respCode = jsonToMapResp.get("respCode").toString();
                    if(respCode.equals("000000")){
                        String client = jsonToMapResp.get("client").toString();
                        Map<String, Object> jsonToMapClient = JsonUtil.JsonToMap(client);
                        Map<String,String> resultMap = new HashMap<>();
                        resultMap.put("clientNumber",jsonToMapClient.get("clientNumber").toString());
                        resultMap.put("clientPwd",jsonToMapClient.get("clientPwd").toString());
                        resultMap.put("loginToken",jsonToMapClient.get("loginToken").toString());
                        resultMap.put("createDate",jsonToMapClient.get("createDate").toString());
                        resultMap.put("lykzUserId",jsonToMapClient.get("userId").toString());
                        resultMap.put("mobile",jsonToMapClient.get("mobile").toString());
                        System.out.println(resultMap.toString());
                        return resultMap;
                    }else{
                        return null;
                    }

                }
            }
        }
        return null;
    }

    /**
     * <desc>
     *      更新SIP账号
     * <desc/>
     * @author Juguang.S
     * @createDate 2018-08-24
     */
    @Override
    public void updateUserSipAccount(String newSipAccount, String userId,String sipPsd) throws Exception {
        iAppUserLykzAccountDao.updateUserSipAccount(newSipAccount,userId,sipPsd);
    }

    /**
     * <desc>
     *      获取所有未禁用的项目编号
     * <desc/>
     * @author Juguang.S
     * @createDate 2018-09-04
     */
    @Override
    public List<String> getProjectid() throws Exception {
        return iAppUserLykzAccountDao.getProjectid();
    }

    /**
     * <desc>
     *      因集成灵云快智测试需要，根据userId释放灵云快智账号，前端移动端无需调此接口
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018-09-11
     */
    @Override
    public void dropSipAccount() throws Exception {
        cachedThreadPool.execute(() -> {
            SimpleDateFormat sd = new SimpleDateFormat("yyyyMMddHHmmss");
            String nowTime = sd.format(new Date());
            String sigParameter = Md5EncryptUtil.md5(String.format("%s%s%s", LYKZ_ACCOUNT_SID, LYKZ_ACCOUNT_TOKEN, nowTime)).toUpperCase();
            String url = "http://" + LYKZ_URL + ":" + LYKZ_PORT + "/ucsrtc-rest-api/" + LYKZ_SOFT_VERSION + "/Accounts/" + LYKZ_ACCOUNT_SID + "/dropClient?sig=" + sigParameter;

            List<String> userIdList = iAppUserLykzAccountDao.getLykzUserId();
            if (userIdList.size() > 0) {
                for (String userStr : userIdList) {
                    if (StringUtils.isNotEmpty(userStr)) {
                        Map<String, Object> params = new HashMap<>();
                        Map<String, String> map = new HashMap<>();
                        map.put("appId", LYKZ_APPID);
                        map.put("userId", userStr);
                        params.put("client", map);
                        String paramsStr = JSON.toJSONString(params);

                        String responseStr = HttpProtocolUtil.httpPostByLykz(url, paramsStr, nowTime,LYKZ_ACCOUNT_SID);
                        if (StringUtils.isNotEmpty(responseStr)) {
                            Map<String, Object> jsonToMap = JsonUtil.JsonToMap(responseStr);
                            if (jsonToMap != null && !jsonToMap.isEmpty()) {
                                Map<String, Object> jsonToMapResp = JsonUtil.JsonToMap(jsonToMap.get("resp").toString());
                                if (jsonToMapResp != null && !jsonToMapResp.isEmpty()) {
                                    String respCode = jsonToMapResp.get("respCode").toString();
                                    if (!respCode.equals("000000")) {
                                        //LOG.info("【灵云快智账号删除失败】"+userStr);
                                        System.out.println("删除失败" + userStr);

                                    } else {
                                        //LOG.info("【灵云快智账号删除成功】"+userStr);
                                        System.out.println("删除成功" + userStr);
                                    }

                                }
                            }
                        }
                    }
                }
            }
        });

    }

    /**
     * <desc>
     *      根据userId查询是否已创建灵云快智的账号
     * </desc>
     *
     * @param userId 用户id
     * @return
     * @author Juguang.S
     * @createDate 2018/08/24
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Integer getUserInfoByUserId(String userId) throws Exception {
        return iAppUserLykzAccountDao.getUserInfoByUserId(userId);
    }

    /**
     * <desc>
     *      根据灵云userid查询cloud_intercom_account_info表中是否已有该用户灵云信息数据
     * <desc/>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018-11-22
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.NOT_SUPPORTED)
    public Integer getExistLykzInfo(String lykzUserID) {
        return iAppUserLykzAccountDao.getExistLykzInfo(lykzUserID);
    }

}
